#include<cstdlib>
#include<iostream>
#include <memory>
#include <crtdbg.h> 
#include <list>
#include <string>
using namespace std;
class Product
{
public:
	Product():mList(){}
	~Product(){}
	void Add(string iItemStr)
	{
		mList.push_back(iItemStr);
	}
	Product* CreateCopy()
	{
		Product* lpProduct = new Product();
		for (list<string>::iterator it = mList.begin(); it != mList.end(); ++it)
		{
			lpProduct->Add(*it);
		}
		return lpProduct;
	}
	void Display()
	{
		int i = 0;
		for (list<string>::iterator it = mList.begin(); it != mList.end(); ++it)
		{
			cout<<"The "<< ++i<<"th member: " << *it<<"\t"; 
		}
		cout << endl;
	}

private:
	list<string> mList; 

};
class Builder
{
public:
	virtual void BuildPartA() = 0;
	virtual void BuildPartB() = 0;

	virtual Product* GetProduct() = 0;
};

class ConcreteBuilder1 : public Builder
{
public:
	ConcreteBuilder1():mpProduct(){}
	void BuildPartA()
	{
		mpProduct.Add("ConcreteBuilder1_A");
	}
	void BuildPartB()
	{
		mpProduct.Add("ConcreteBuilder1_B");
	}
	Product* GetProduct()
	{
		return mpProduct.CreateCopy();
	}

private:
	Product mpProduct; 
};

class ConcreteBuilder2 : public Builder
{
public:
	ConcreteBuilder2():mpProduct(){}
	void BuildPartA()
	{
		mpProduct.Add("ConcreteBuilder2_A");
	}
	void BuildPartB()
	{
		mpProduct.Add("ConcreteBuilder2_B");
	}
	Product* GetProduct()
	{
		return mpProduct.CreateCopy();
	}
private:
	Product mpProduct; 
};

class Director
{
public:
	
	void Construct(Builder* lpBuilder)
	{
		lpBuilder->BuildPartA();
		lpBuilder->BuildPartB();
	}
};

int main()
{
	Director lDirector;
	Builder* lpBuilder1 = new ConcreteBuilder1();
	lDirector.Construct(lpBuilder1);
	Product* p1 = lpBuilder1->GetProduct();
	p1->Display();
	
	Builder* lpBuilder2 = new ConcreteBuilder2();
	lDirector.Construct(lpBuilder2);
	Product* p2= lpBuilder2->GetProduct();
	p2->Display();

	getchar();
	delete lpBuilder1;
	delete p1;
	delete p2;
}